#pragma once

#include <iostream>
#include "log.hpp"
#include <string>
#include <jsoncpp/json/json.h>

//#define MySelf 1

const std::string blank=" ";
const std::string newline="\n";


/*问题：我们需要一个什么？需要一个网络计算器，因此我们需要一个结构体，负责拿到2个数据以及计算标识符，
返回需要返回结果和结果的标志位，以上2个结构体构成request和response，但是2个结构体在传输中需要进行序列和反序列，因此需要一个应用层协议（表示层），
我们按“ABCD\nX ? Y\n”的格式进行发从，其中ABCD表示X→Y的字符数数量，？表示计算符

*/

std::string Encode(std::string &content)
{
    std::string tmp=std::to_string(content.size());
    tmp+=newline;
    tmp+=content;
    tmp+=newline;
    return tmp;
}


bool Decode(std::string &package,std::string *content)
{
    size_t pos=package.find(newline);
    if(pos==std::string::npos)  return false;
    std::string str_len=package.substr(0,pos);
    int len=stoi(str_len);
    int title_len=str_len.size()+len+2;
    if(package.size()<title_len)   return false;
    *content=package.substr(pos+1,len);
    package.erase(0,title_len);
    return true;
}


class Request
{

public:
    Request(int date1,char oper,int date2)
    :_x(date1),_y(date2),_op(oper)
    {}

    ~Request()
    {}
public:
    bool Serialize(std::string *out)
    {
#ifdef MySelf
        std::string s = std::to_string(_x);
        s+=blank;
        s+=_op;
        s+=blank;
        s+=std::to_string(_y);
        *out=s;
        return true;
#else
        Json::Value root;
        root["x"] = _x;
        root["y"] = _y;
        root["op"] = _op;
        Json::StyledWriter w;
        *out = w.write(root);
        return true;

#endif
    }

    bool Deserialization(const std::string &in)
    {
#ifdef MySelf
        std::size_t left = in.find(blank);
        if(left==std::string::npos)
            return false;
        std::string part_x = in.substr(0,left);

        std::size_t right = in.rfind(blank);
        if(right==std::string::npos)
            return false;
        std::string part_y = in.substr(right+1);

        if(left+2 != right)
            return false;
        _op = in[left+1];
        _x = std::stoi(part_x);
        _y = std::stoi(part_y);
        return true;
#else
        Json::Value root;
        Json::Reader r;
        r.parse(in,root);

        _x=root["x"].asInt();
        _y=root["y"].asInt();
        _op=root["op"].asInt();
        return true;

#endif
    }

    void DebugPrint()
    {
        std::cout << "新请求构建完成:  " << _x << _op << _y << "=?" << std::endl;
    }

private:
public:
    int _x;
    int _y;
    char _op;
};



class Response
{

public:
    Response(std::string result,int code)
    :_result(result),_code(code)
    {}
    ~Response()
    {}
public:
    bool Serialize(std::string *out)
    {
#ifdef MySelf
        std::string s = _result;
        s+=blank;
        s+=std::to_string(_code);
        *out=s;
        return true;
#else
        Json::Value root;
        root["code"] = _code;
        root["result"] = _result;
        Json::StyledWriter w;
        *out = w.write(root);
        return true;
#endif

    }

    bool Deserialize(const std::string &in)
    {
#ifdef MySelf
        std::size_t left = in.find(blank);
        if(left==std::string::npos)
            return false;
        //_result = std::stoi(in.substr(0,left));
        _result = in.substr(0,left);
        _code = std::stoi(in.substr(left+1));
        return true;
#else
        Json::Value root;
        Json::Reader r;
        r.parse(in,root);

        _result=root["result"].asString();
        _code=root["code"].asInt();
        return true;
#endif
    }
private:
public:
    //int _result;
    std::string _result;
    int _code;
};